package org.example;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

//自定义的多重 map 可以根据键获取值的集合
public class ConcurrentMultimap<K, V> implements Map<K, Collection<V>> {

    //实际容器
    private final ConcurrentHashMap<K, Collection<V>> map;

    //集合提供商 存实际的集合的new方法 所以这个get相当于new集合
    private final Supplier<Collection<V>> collectionSupplier;


    //检查类型的调试方法
    public void checkType(){

        System.out.println("The collection type is: " + collectionSupplier.get().getClass().getName());    }



    // 可以传集合的构造方法 new
    public ConcurrentMultimap(Supplier<Collection<V>> collectionSupplier) {
        if (collectionSupplier == null) {
            throw new IllegalArgumentException("collectionSupplier cannot be null");
        }
        map = new ConcurrentHashMap<>();
        this.collectionSupplier = collectionSupplier;
    }

    //无参构造 默认用HashSet 给他们反射用
//    public ConcurrentMultimap() {
//        this(LinkedHashSet::new);
//    }

    //核心方法 向某个键的集合中添加一个值
    public void putValue(K key, V value) {
        map.computeIfAbsent(key, k -> collectionSupplier.get()).add(value);
    }




    // 通过键获取值的集合
    @Override
    public Collection<V> get(Object key) {
        Collection<V> result = map.get(key);
        return result != null ? result : collectionSupplier.get();
    }

    // put完整键值对 要适配 内部规定的集合
    @Override
    public Collection<V> put(K key, Collection<V> value) {
        // 检查 value 是否已经是预期的集合类型
        if (value instanceof LinkedHashSet) {
            // 如果是 LinkedHashSet 直接存储
            return map.put(key, value);
        } else {
            // 如果不是预期类型，创建新的集合，并将元素逐个添加进去
            Collection<V> adaptedCollection = collectionSupplier.get();
            adaptedCollection.addAll(value);  // 将原集合的所有元素添加到适配的集合中
            return map.put(key, adaptedCollection);
        }
    }

    // 删除某个键对应的集合
    @Override
    public Collection<V> remove(Object key) {

        return map.remove(key);
    }

    // 返回所有的键
    @Override
    public Set<K> keySet() {
        return map.keySet();
    }

    // 返回所有值的集合（每个键对应的集合）
    @Override
    public Collection<Collection<V>> values() {
        throw new UnsupportedOperationException("values is not supported");
    }

    // 返回所有的键值对
    @Override
    public Set<Entry<K, Collection<V>>> entrySet() {
        return map.entrySet();
    }

    // 检查是否包含某个键
    @Override
    public boolean containsKey(Object key) {
        return map.containsKey(key);
    }

    // 这玩意不用 直接抛异常
    @Override
    public boolean containsValue(Object value) {
        throw new UnsupportedOperationException("containsValue is not supported");
    }

    // 获取键集的大小
    @Override
    public int size() {
        return map.size();
    }

    // 判断集合是否为空
    @Override
    public boolean isEmpty() {
        return map.isEmpty();
    }

    // 清空集合
    @Override
    public void clear() {
        map.clear();
    }

    @Override
    public void putAll(Map<? extends K, ? extends Collection<V>> m) {
        for(Map.Entry<? extends K, ? extends Collection<V>> entry : m.entrySet()){
            put(entry.getKey(), entry.getValue());
        }
    }
}
